package com.fxu.gen;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fxu.framework.biz.base.Limits;
import com.fxu.framework.biz.util.BizUtil;
import com.fxu.framework.core.base.Cascade;
import com.fxu.framework.core.base.Constant;
import com.fxu.framework.core.enums.*;
import com.fxu.framework.core.handler.ListLongTypeHandler;
import com.fxu.framework.core.handler.ListStringTypeHandler;
import com.fxu.gen.enums.ClnType;
import com.fxu.gen.enums.FormType;
import com.fxu.gen.enums.SignEnum;
import com.fxu.gen.enums.TplEnum;
import com.fxu.tpl.entity.Column;
import com.fxu.tpl.entity.Link;
import com.fxu.tpl.entity.Table;
import lombok.Data;

import javax.validation.Valid;
import javax.validation.constraints.*;
import java.io.File;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.Random;

/**
 * Entity类的模板替换
 * @author fangxu
 * @version 1.0.0
 */
public final class Entity extends Base {
	public static final List<String> blzs = StrUtil.split("ADD,ALL,ALTER,ANALYZE,AND,AS,ASC,ASENSITIVE,BEFORE," +
			"BETWEEN,BIGINT,BINARY,BLOB,BOTH,BY,CALL,CASCADE,CASE,CHANGE,CHAR,CHARACTER,CHECK,COLLATE,COLUMN,MODIFY," +
			"CONDITION,CONNECTION,CONSTRAINT,CONTINUE,CONVERT,CREATE,CROSS,CURRENT_DATE,CURRENT_TIME,CURRENT_USER," +
			"CURSOR,DATABASE,DATABASES,DAY_HOUR,DAY_MICROSECOND,DAY_MINUTE,DAY_SECOND,DEC,DECIMAL,DECLARE,DEFAULT," +
			"DELAYED,DELETE,DESC,DESCRIBE,DETERMINISTIC,DISTINCT,DISTINCTROW,DIV,DOUBLE,DROP,DUAL,EACH,ELSE,ELSEIF," +
			"ENCLOSED,ESCAPED,EXISTS,EXIT,EXPLAIN,FALSE,FETCH,FLOAT,FLOAT4,FLOAT8,FOR,FORCE,FOREIGN,FROM,FULLTEXT," +
			"GOTO,GRANT,GROUP,HAVING,HIGH_PRIORITY,HOUR_MICROSECOND,HOUR_MINUTE,HOUR_SECOND,IF,IGNORE,IN,INDEX," +
			"INFILE,INNER,INOUT,INSENSITIVE,INSERT,INT,INT1,INT2,INT3,INT4,INT8,INTEGER,INTERVAL,INTO,IS,ITERATE," +
			"JOIN,KEY,KEYS,KILL,LABEL,LEADING,LEAVE,LEFT,LIKE,LIMIT,LINEAR,LINES,LOAD,LOCALTIME,LOCALTIMESTAMP,LOCK," +
			"LONG,LONGBLOB,LONGTEXT,LOOP,LOW_PRIORITY,MATCH,MEDIUMBLOB,MEDIUMINT,MEDIUMTEXT,MIDDLEINT,MOD,MODIFIES," +
			"NATURAL,NOT,NULL,NUMERIC,ON,OPTIMIZE,OPTION,OPTIONALLY,OR,ORDER,OUT,OUTER,OUTFILE,PRECISION,PRIMARY," +
			"PROCEDURE,PURGE,RAID0,RANGE,READ,READS,REAL,REFERENCES,REGEXP,RELEASE,RENAME,REPEAT,REPLACE,REQUIRE," +
			"RESTRICT,RETURN,REVOKE,RIGHT,RLIKE,SCHEMA,SCHEMAS,SELECT,SENSITIVE,SEPARATOR,SET,SHOW,SMALLINT,SPATIAL," +
			"SPECIFIC,SQL,SSL,STARTING,STRAIGHT_JOIN,TABLE,TERMINATED,THEN,TINYBLOB,TINYINT,TINYTEXT,TO,TRAILING," +
			"TRIGGER,TRUE,UNDO,UNION,UNIQUE,UNLOCK,UNSIGNED,UPDATE,USAGE,USE,USING,VALUES,VARBINARY,VARCHAR," +
			"VARCHARACTER,VARYING,WHEN,WHERE,WHILE,WITH,WRITE,XOR,YEAR_MONTH,ZEROFILL,FIRST_VALUE", ",");

	public Entity(Table table, File destFile) {
		super(table, TplEnum.Entity, destFile);
	}
	
	@Override
	public String doReplace() {
		String fileTxt = super.doReplace();
		fileTxt = replace(fileTxt, SignEnum.EntityColumn, getColumn());
		fileTxt = fileTxt.replace(fileTxt.substring(fileTxt.indexOf("@ApiModel("), fileTxt.indexOf("\")") + 2), getApiModel());
		int index = fileTxt.indexOf("@TableName(");
		if (index > -1) {
			String temp = fileTxt.substring(index);
			temp = temp.substring(0, temp.indexOf(")") + 1);
			fileTxt = fileTxt.replace(temp, getTableName());
		}
		fileTxt = replaceImports(fileTxt, false); //放最后才能收集imports
		return fileTxt;
	}
	
	private String getTableName() {
		return String.format("@TableName(value = \"%s\", autoResultMap = true)", table.getName());
	}
	
	private String getApiModel() {
		return String.format("@ApiModel(value = \"%s\", description = \"%s\")", tableBean, table.getCmmt());
	}

	private StringBuffer getColumn() {
		StrBuf buffer = new StrBuf();

		String priKeyCln = getPriKeyClnName(columns);
		buffer.append(1, "private static final long serialVersionUID = {1}L;\n", new Random().nextLong());
		for (Column column : columns) {
			String clnName = column.getName();
			if (priKeyCln.equals(clnName)) {
				if ((Objects.equals(column.getType(), ClnType.LONG.code()) || Objects.equals(column.getType(), ClnType.INTEGER.code()))) {
					buffer.append(1, "@TableId(type = IdType.AUTO)");
				} else {
					buffer.append(1, "@TableId");
				}
			}
			if (blzs.contains(clnName.toUpperCase())) {
				buffer.append(1, "@TableField(\"`{1}`\")", clnName);
				AutoUtil.toImports(imports, TableField.class);
			}
			// 密码不显示
			if (clnName.equals("pswd") || clnName.endsWith("password") || clnName.endsWith("pwd")) {
				buffer.append(1, "@JsonIgnore");
				AutoUtil.toImports(imports, JsonIgnore.class);
			}
			// 时间选择日期
			if (Objects.equals(column.getFormType(), FormType.DATE.code()) && !Constant.CLN_CREATE_TIME.equals(clnName)
					&& !Constant.CLN_MODIFY_TIME.equals(clnName)) {
				buffer.append(1, "@JsonFormat(pattern = \"yyyy-MM-dd\")");
				AutoUtil.toImports(imports, JsonFormat.class);
			}
			// 字段包含_数字
			if (AutoUtil.hasSpecialNumber(column.getName())) {
				buffer.append(1, "@TableField(\""+ column.getName() +"\")");
			}
			// 大字段不默认读取
			if (column.isText()) {
				buffer.append(1, "@TableField(select = false)");
			}
			if (Constant.CLN_VERSION.equals(column.getName())) {
				buffer.append(1, "@TableField(fill = UPDATE, update = \"%s+1\")");
			} else if (Constant.CLN_CREATE_BY.equals(column.getName())) {
				buffer.append(1, "@TableField(fill = INSERT)");
			} else if (Constant.CLN_MODIFY_BY.equals(column.getName())) {
				buffer.append(1, "@TableField(fill = UPDATE)");
			}

			buffer.append(1, getApiModelProperty(column));
			if (!(priKeyCln.equals(column.getName()) || Constant.CLN_VERSION.equals(column.getName())
					|| Constant.CLN_CREATE_BY.equals(column.getName()) || Constant.CLN_CREATE_TIME.equals(column.getName())
					|| Constant.CLN_MODIFY_BY.equals(column.getName()) || Constant.CLN_MODIFY_TIME.equals(column.getName()))) {
				buffer.append(getAnnotation(column));
			}
			String typeText = column.getTypeText();
			if (column.isText()) {
				typeText = "String";
			}
			if (column.isDecimal()) {
				typeText = "BigDecimal";
			}

			// 含有集合字段
			if (column.getName().endsWith("_ids")) {
				buffer.append(1, "@TableField(typeHandler = ListLongTypeHandler.class)");
				AutoUtil.toImports(imports, ListLongTypeHandler.class);
				typeText = "List<Long>";
			} else if (column.getName().endsWith("s") && (column.getCmmt().endsWith("集合") || column.getCmmt().endsWith("集"))) {
				buffer.append(1, "@TableField(typeHandler = ListStringTypeHandler.class)");
				AutoUtil.toImports(imports, ListStringTypeHandler.class);
				typeText = "List<String>";
			} else if (StrUtil.isNotEmpty(column.getLimits()) && column.getLimits().startsWith("{") && column.getLimits().endsWith("}")) {
				buffer.append(1, "@TableField(typeHandler = JacksonTypeHandler.class)");
				AutoUtil.toImports(imports, JacksonTypeHandler.class);
				String tmp = AutoUtil.getBean(column.getName());
				typeText = column.getName().endsWith("s") ? "List<"+tmp.substring(0, tmp.length() - 1)+">" : tmp;
			}

			AutoUtil.toImports(imports, column.isDate() ? Date.class : null);
			AutoUtil.toImports(imports, column.isFloat() ? Float.class : null);
			AutoUtil.toImports(imports, column.isDouble() ? Double.class : null);
			AutoUtil.toImports(imports, column.isDecimal() ? BigDecimal.class : null);
			buffer.append(1, "private {1} {2};\n", typeText, AutoUtil.firstLowerBean(column.getName()));
		}
		// 一对一链接对象
		for (Column column : columns) {
			if (column.getLinkTable() != null && (column.getFormType() == null || !Objects.equals(column.getFormType(), FormType.MY_CONF.code()))) {
				String linkTableBean = AutoUtil.getBean(column.getLinkTable().getName());
				String linkTableBeanAll = getTablePackage(column.getLinkTable()) + "." + linkTableBean; //.replace(".entity", ".feign")
				if (isTrue(column.getLinkSave())) {
					buffer.append(1, "@Valid");
				}
				// 简单判断唯一字段
				Column linkTablePriKey = getPriKeyColumn(column.getLinkTable().getColumnList());
				if (column.getName().endsWith("_ids")) {
					buffer.append(1, "@TableField(exist = false)");
					buffer.append(1, "@ApiModelProperty(value = \"{1}\")", column.getCmmt().replace("ID集合", "对象集合").replace("ID", ""));
					buffer.append(1, getCascade(AutoUtil.firstLowerBean(column.getName()), linkTablePriKey == null ? Constant.ID_NAME : linkTablePriKey.getName(), isTrue(column.getLinkSave())));
					buffer.append(1, "private List<{1}> {2};\n", linkTableBean, AutoUtil.firstLowerBean(column.getName().replace("_ids", "_list")));
				} else {
					buffer.append(1, "@TableField(exist = false)");
					buffer.append(1, "@ApiModelProperty(value = \"{1}\")", column.getCmmt().replace("ID", ""));
					buffer.append(1, getCascade(AutoUtil.firstLowerBean(column.getName()), linkTablePriKey == null ? Constant.ID_NAME : linkTablePriKey.getName(), isTrue(column.getLinkSave())));
					buffer.append(1, "private {1} {2};\n", linkTableBean, AutoUtil.firstLowerBean(column.getName().replace("_id", "")));
				}
				if (!this.thisPackage.replace(".null.", "." + this.thisModule + ".").equals(getTablePackage(column.getLinkTable()))) {
					AutoUtil.toImports(imports, linkTableBeanAll);
				}
			}
		}
		// 一对多链接对象
		for (Link link : links) {
			if (link.getLinkTable() != null && link.getLinkColumn() != null) {
				String linkTablePackage = getTablePackage(link.getLinkTable());
				String linkTableBean = AutoUtil.getBean(link.getLinkTable().getName());
				String linkTableBeanAll = linkTablePackage + "." + linkTableBean;
				String linkTableName = getLinkPropName(link);
				if (isTrue(link.getLinkSave())) {
					buffer.append(1, "@Valid");
				}
				buffer.append(1, "@TableField(exist = false)");
				if (isTrue(link.getIsList())) {
					buffer.append(1, "@ApiModelProperty(value = \"{1}\")", link.getLinkTable().getCmmt());
					buffer.append(1, getCascade(priKeyCln, AutoUtil.firstLowerBean(link.getLinkColumn().getName()), isTrue(link.getLinkSave())));
					buffer.append(1, "private List<{1}> {2}s;\n", linkTableBean, linkTableName);
					if (!this.thisPackage.replace(".null.", "." + this.thisModule + ".").equals(linkTablePackage)) {
						AutoUtil.toImports(imports, linkTableBeanAll);
					}
				} else {
					buffer.append(1, "@ApiModelProperty(value = \"{1}\")", link.getLinkTable().getCmmt());
					buffer.append(1, getCascade(priKeyCln, AutoUtil.firstLowerBean(link.getLinkColumn().getName()), isTrue(link.getLinkSave())));
					buffer.append(1, "private {1} {2};\n", linkTableBean, linkTableName);
				}
			}
		}
		// 含有pid字段增加children
		if (AutoUtil.hasColumn(columns, Constant.NEW_PARENT_ID)) {
			buffer.append(1, "@TableField(exist = false)");
			buffer.append(1, "@ApiModelProperty(value = \"子列表\")");
			buffer.append(1, getCascade(priKeyCln, Constant.NEW_PARENT_ID, false));
			buffer.append(1, "private List<{1}> children;\n", tableBean);
		}

		for (Column column : columns) {
			// 含有limits字段返回中文解释
			if (hasLimits(column.getLimits()) && column.getLimits().contains(":")) {
				buffer.append(1, "/** 获得{1}的组合 */", column.getCmmt());
				buffer.append(1, "public String get{1}Text() {", AutoUtil.getBean(column.getName()));
				buffer.append(2, "return {1}.desc({2});", getEnumName(tableBean, column), AutoUtil.firstLowerBean(column.getName()));
				buffer.append(1, "}");
			}

			// 含有limits且为对象
			if (StrUtil.isNotEmpty(column.getLimits()) && column.getLimits().startsWith("{") && column.getLimits().endsWith("}")) {
				String clazz = AutoUtil.getBean(column.getName());
				clazz = clazz.endsWith("s") ? clazz.substring(0, clazz.length() - 1) : clazz;
				String limits = column.getLimits().substring(1, column.getLimits().length() - 1);
				String newTxt = fileTxt;
				newTxt = replace(newTxt, SignEnum.ClassAuto, new StringBuffer());
				String method = "public static class " + clazz + " {";
				if (!newTxt.contains(method)) {
					buffer.append(1, "/** {1}的类 */", column.getCmmt());
					buffer.append(1, "@Data");
					buffer.append(1, "public static class {1} {", clazz);
					for (String s : limits.split(";")) {
						if (s.indexOf(":") > 0) {
							buffer.append(2, "/** {1} */", s.substring(0, s.indexOf(":")));
							buffer.append(2, "private {1};", s.substring(s.indexOf(":") + 1));
						} else {
							buffer.append(2, "private {1};", s);
						}
					}
					buffer.append(1, "}");
					AutoUtil.toImports(imports, Data.class);
				}
			}
			// 含有List<>返回名字集合
			if (column.getName().endsWith("_ids")) {
				String name = AutoUtil.firstLowerBean(column.getName().replace("_ids", "_list"));
				String linkTableBean = AutoUtil.getBean(column.getLinkTable().getName());
				String linkShowCln = column.getLinkTable() == null ? "" : column.getLinkTable().getShowCln();
				buffer.append(1, "/** 获得{1}的展示 */", column.getCmmt());
				buffer.append(1, "public String get{1}Text() {", StrUtil.upperFirst(name));
				buffer.append(2, "return BizUtil.toText({1}, {2}::get{3});", name, linkTableBean, StrUtil.upperFirst(linkShowCln));
				buffer.append(1, "}");
			} else if (column.getName().endsWith("s") && (column.getCmmt().endsWith("集合") || column.getCmmt().endsWith("集"))) {
				String name = AutoUtil.firstLowerBean(column.getName());
				buffer.append(1, "/** 获得{1}的展示 */", column.getCmmt());
				buffer.append(1, "public String get{1}Text() {", StrUtil.upperFirst(name));
				buffer.append(2, "return BizUtil.toText({1});", name);
				buffer.append(1, "}");
			}
		}
		StringBuffer stringBuffer = buffer.toBuffer();
		if (stringBuffer.indexOf("List<") > -1) {
			AutoUtil.toImports(imports, List.class);
		}
		if (stringBuffer.indexOf("@Cascade") > -1) {
			AutoUtil.toImports(imports, Cascade.class);
		}
		if (stringBuffer.indexOf("@Valid") > -1) {
			AutoUtil.toImports(imports, Valid.class);
		}
		if (stringBuffer.indexOf("BizUtil.") > -1) {
			AutoUtil.toImports(imports, BizUtil.class);
		}
		return stringBuffer;
	}

	public static String getEnumName(String tableBean, Column column) {
		if (Constant.CLN_STATUS.equals(column.getName()) && StatusEnum.is(column.getLimits())) {
			return StatusEnum.class.getSimpleName();
		} else if (Constant.CLN_STATUS.equals(column.getName()) && ShowStatus.is(column.getLimits())) {
			return ShowStatus.class.getSimpleName();
		} else if (Constant.CLN_STATUS.equals(column.getName()) && ShowStrStatus.is(column.getLimits())) {
			return ShowStrStatus.class.getSimpleName();
		} else if (Constant.CLN_STATUS.equals(column.getName()) && StrStatus.is(column.getLimits())) {
			return StrStatus.class.getSimpleName();
		} else if (Constant.CLN_STATUS.equals(column.getName()) && ProcessStatus.is(column.getLimits())) {
			return ProcessStatus.class.getSimpleName();
		} else if (Constant.CLN_PRIORITY.equals(column.getName()) && PriorityEnum.is(column.getLimits())) {
			return PriorityEnum.class.getSimpleName();
		} else if (AuditStatus.is(column.getLimits())) {
			return AuditStatus.class.getSimpleName();
		} else {
			// + "Enum"
			return tableBean + AutoUtil.getBean(column.getName());
		}
	}
	
	private static String getCascade(String thisField, String linkField, boolean isSave) {
		String tpl = "@Cascade(thisField = \"{1}\", linkField = \"{2}\"{3})";
		return StrBuf.format(tpl, thisField, linkField, isSave ? ", save = true" : "");
	}
	
	private static String getApiModelProperty(Column column) {
		String tpl = "@ApiModelProperty(value = \"{1}\"{2})";
		String comment = column.getCmmt();
		if (hasLimits(column.getLimits()) && !comment.contains(column.getLimits())) {
			comment += "[" + column.getLimits() + "]";
		}
		/*if (column.getQueryType() != null) {
			comment += "[支持" + column.getQueryTypeText() + "搜索]";
		}*/
		return StrBuf.format(tpl, comment, isTrue(column.getNotNull()) && isTrue(column.getRequired()) ? ", required = true" : "");
	}

	private String getAnnotation(Column column) {
		StrBuf buffer = new StrBuf();
		// 都加上，去掉代码比较容易 && column.getRequired() != null && !column.getRequired() && column.getDefVal() == null &&
		if (isTrue(column.getNotNull()) && isTrue(column.getRequired()) && !Constant.CLN_STATUS.equals(column.getName())) {
			// 含有集合字段
			if (!column.isString() || column.getName().endsWith("_ids") ||
					(column.getName().endsWith("s") && (column.getCmmt().endsWith("集合") || column.getCmmt().endsWith("集")))) {
				buffer.append(1, "@NotNull(message = \"{1}必须赋值\")", column.getCmmt());
				AutoUtil.toImports(imports, NotNull.class);
			} else {
				buffer.append(1, "@NotBlank(message = \"{1}必须赋值\")", column.getCmmt());
				AutoUtil.toImports(imports, NotBlank.class);
			}
		}
		if (column.isDecimal()) {
			buffer.append(1, "@Digits(integer = {1}, fraction = {2}, message = \"{3}的精度必须整数位:{1},小数位:{2}\")",
					column.getLength(), column.getDotRight(), column.getCmmt());
			AutoUtil.toImports(imports, Digits.class);
			//TODO 最小值 最大值 => String
			/*if (column.getValidMin() != null && column.getValidMin() > 0) {
				buffer.append(1, "@DecimalMin(value = \"{1}\", message = \"{2}必须大于{1}\")", column.getValidMin(), column.getCmmt());
				AutoUtil.toImports(imports, "javax.validation.constraints.DecimalMin");
			}
			if (column.getValidMax() != null) {
				buffer.append(1, "@DecimalMax(value = \"{1}\", message = \"{2}必须小于{1}\")", column.getValidMax(), column.getCmmt());
				AutoUtil.toImports(imports, "javax.validation.constraints.DecimalMax");
			}*/
		}
		if (column.isString()) {
			long minLen = column.getValidMin() != null && column.getValidMin() > 0 ? column.getValidMin() : 0;
			long maxLen = column.getLength();
			if (column.getValidMax() != null && column.getValidMax() > 0) {
				maxLen = column.getLength() < column.getValidMax() ? column.getLength() : column.getValidMax();
			}
			if (minLen > 0) {
				buffer.append(1, "@Size(min = {1}, max = {2}, message = \"{3}的长度必须在{1}到{2}位之间\")", minLen, maxLen, column.getCmmt());
			} else if (maxLen > 0) {
				buffer.append(1, "@Size(max = {1}, message = \"{2}的长度必须小于{1}位\")", maxLen, column.getCmmt());
			}
			AutoUtil.toImports(imports, Size.class);
		}
		if (column.isNumber()) {
			if (column.getValidMin() != null && column.getValidMin() > 0) {
				buffer.append(1, "@Min(value = {1}, message = \"{2}的值必须大于{1}\")", column.getValidMin(), column.getCmmt());
				AutoUtil.toImports(imports, Min.class);
			}
			if (column.getValidMax() != null && column.getValidMax() > 0) {
				buffer.append(1, "@Max(value = {1}, message = \"{2}的值必须小于{1}\")", column.getValidMax(), column.getCmmt());
				AutoUtil.toImports(imports, Max.class);
			}
		}

		if (hasLimits(column.getLimits())) {
			String enumName = getEnumName(tableBean, column);
			if (!enumName.startsWith(tableBean)) {
				AutoUtil.toImports(imports, corePackage + ".enums." + enumName);
			} else {
				// 新生成枚举类
				saveEnumsFile(table, TplEnum.Enums, enumName + ".java", column.getLimits());
				AutoUtil.toImports(imports, this.thisPackage.replace(".entity", ".enums.") + enumName);
			}
			buffer.append(1, "@EnumValid(target = {1}.class, message = \"{2}的值必须为[{3}]\")", enumName, column.getCmmt(), column.getLimits());
			AutoUtil.toImports(imports, EnumValid.class);
		}

		if (!StrUtil.isEmpty(column.getValidFun())) {
			buffer.append(1, "@Pattern(regexp = \"{1}\", message = \"{2}格式不正确\")", column.getValidFun(), column.getName());
			AutoUtil.toImports(imports, Pattern.class);
		}
		return buffer.toString();
	}

	public static boolean hasLimits(String limits) {
		return StrUtil.isNotEmpty(limits) && !limits.startsWith("{");
	}

	private static final char[] names = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
	//第三步根据模板生成新表所有代码
	private String saveEnumsFile(Table table, TplEnum tplEnum, String fileName, String limitStr) {
		String newPath = project.getDstPath() + table.getModule().getFolder() + "/"
				+ tplEnum.getSrcPath(project.getDstProject(), table.getModule().getName());
		File newFile = new File(newPath + fileName);
		LimitEnum limitEnum = new LimitEnum(table, newFile);
		if (newFile.exists()) {
			System.out.println("文件已经存在，不进行修改:" + newFile);
		} else {
			Limits limits = new Limits(limitStr);
			boolean isNumber = BaseEnum.hasAny(limits.getDictList(), v -> v.getIntKey() != null);
			String fileTxt = limitEnum.doReplace();
			if (!isNumber) {
				fileTxt = fileTxt.replace("Integer ", "String ");
			}
			String prev = fileTxt.substring(0, fileTxt.indexOf("public enum "));
			String next = fileTxt.substring(fileTxt.indexOf("{") + 1);
			next = next.substring(next.indexOf(";"));
			StrBuf buffer = new StrBuf(prev);
			buffer.append(0, "public enum {1} implements BaseEnum<{2}, String> {",
					fileName.replace(".java", ""), isNumber ? "Integer" : "String");

			int ind = 0;
			for (Limits.Dict dict : limits.getDictList()) {
				if (dict.getIntKey() != null) {
					buffer.append(1, "{1}({2}, \"{3}\"),", names[ind++], dict.getIntKey(), dict.getValue());
				} else {
					buffer.append(1, "{1}(\"{1}\", \"{2}\"),", dict.getStrKey(), dict.getValue());
				}
			}
			buffer.append(1, next);
			System.out.println("新生成文件:" + newFile);
			FileUtil.writeUtf8String(buffer.toString(), newFile);
		}
		return null;
	}
}
/*
 * mysql 保留词语
 * ADD,ALL,ALTER,ANALYZE,AND,AS,ASC,ASENSITIVE,BEFORE,BETWEEN,BIGINT,BINARY,BLOB,BOTH,BY,CALL,CASCADE,CASE,CHANGE,CHAR,
 * CHARACTER,CHECK,COLLATE,COLUMN,CONDITION,CONNECTION,CONSTRAINT,CONTINUE,CONVERT,CREATE,CROSS,CURRENT_DATE,
 * CURRENT_TIME,CURRENT_TIMESTAMP,CURRENT_USER,CURSOR,DATABASE,DATABASES,DAY_HOUR,DAY_MICROSECOND,DAY_MINUTE,
 * DAY_SECOND,DEC,DECIMAL,DECLARE,DEFAULT,DELAYED,DELETE,DESC,DESCRIBE,DETERMINISTIC,DISTINCT,DISTINCTROW,DIV,DOUBLE,
 * DROP,DUAL,EACH,ELSE,ELSEIF,ENCLOSED,ESCAPED,EXISTS,EXIT,EXPLAIN,FALSE,FETCH,FLOAT,FLOAT4,FLOAT8,FOR,FORCE,FOREIGN,
 * FROM,FULLTEXT,GOTO,GRANT,GROUP,HAVING,HIGH_PRIORITY,HOUR_MICROSECOND,HOUR_MINUTE,HOUR_SECOND,IF,IGNORE,IN,INDEX,
 * INFILE,INNER,INOUT,INSENSITIVE,INSERT,INT,INT1,INT2,INT3,INT4,INT8,INTEGER,INTERVAL,INTO,IS,ITERATE,JOIN,KEY,KEYS,
 * KILL,LABEL,LEADING,LEAVE,LEFT,LIKE,LIMIT,LINEAR,LINES,LOAD,LOCALTIME,LOCALTIMESTAMP,LOCK,LONG,LONGBLOB,LONGTEXT,
 * LOOP,LOW_PRIORITY,MATCH,MEDIUMBLOB,MEDIUMINT,MEDIUMTEXT,MIDDLEINT,MINUTE_MICROSECOND,MINUTE_SECOND,MOD,MODIFIES,
 * NATURAL,NOT,NO_WRITE_TO_BINLOG,NULL,NUMERIC,ON,OPTIMIZE,OPTION,OPTIONALLY,OR,ORDER,OUT,OUTER,OUTFILE,PRECISION,
 * PRIMARY,PROCEDURE,PURGE,RAID0,RANGE,READ,READS,REAL,REFERENCES,REGEXP,RELEASE,RENAME,REPEAT,REPLACE,REQUIRE,
 * RESTRICT,RETURN,REVOKE,RIGHT,RLIKE,SCHEMA,SCHEMAS,SELECT,SENSITIVE,SEPARATOR,SET,SHOW,SMALLINT,SPATIAL,SPECIFIC,
 * SQL,SQLEXCEPTION,SQLSTATE,SQLWARNING,SQL_BIG_RESULT,SQL_CALC_FOUND_ROWS,SQL_SMALL_RESULT,SSL,STARTING,STRAIGHT_JOIN,
 * TABLE,TERMINATED,THEN,TINYBLOB,TINYINT,TINYTEXT,TO,TRAILING,TRIGGER,TRUE,UNDO,UNION,UNIQUE,UNLOCK,UNSIGNED,UPDATE,
 * USAGE,USE,USING,UTC_DATE,UTC_TIME,UTC_TIMESTAMP,VALUES,VARBINARY,VARCHAR,VARCHARACTER,VARYING,WHEN,WHERE,WHILE,WITH,
 * WRITE,X509,XOR,YEAR_MONTH,ZEROFILL
 */